Release 10.1A: OpenEdge Getting Started:
Object-oriented Programming


Constructing an object

You construct a class instance (object) by invoking a NEW statement on the type name of the class, passing any parameters specified by its constructor. (For more information on using the NEW statement, see the "Creating a class instance using the NEW statement" section.) As described previously (see the beginning of the "Inheritance and the class hierarchy" section), when an object of a subclass is instantiated at run time, it is constructed from the top super class of the class hierarchy down. Instantiating from the top down is important because the subclass can reference public and protected methods in its super class during the instantiation process, and Progress must make sure the super class object has been constructed before the subclass invokes any of those methods.

In order to enforce the construction of an object hierarchy from the top of the object hierarchy to the bottom, if the super class constructor has parameters, the first executable statement in the subclass constructor must be an explicit call to its super class constructor using the SUPER statement. If the super class's constructor has no parameters, the call to its constructor is optional. In addition, if the subclass does not need to execute any statements of its own to do initialization work when the subclass is instantiated, it does not need to have a constructor at all. Progress automatically calls the super class constructor, passing no parameters, if the subclass does not explicitly define a constructor.

This is the syntax to invoke the immediate super class constructor using the SUPER statement:

Syntax
SUPER ( [ parameter [ , parameter ] ... ] ) . 

Element descriptions for this syntax diagram follow:

[ parameter [ , parameter ] ... ]

The parameters of the super class's constructor. For more information on the syntax of parameter, see the “Parameter passing syntax” reference entry in OpenEdge Development: Progress 4GL Reference .

Notes: It is a compiler error to specify NO-ERROR on the SUPER statement. Any Progress session error that occurs during execution of a constructor must be handled only by the NEW statement. For more information, see the "Raising and handling error conditions" section

The reference entry for the Progress 4GL SUPER statement is documented with the attributes and methods reference entries as the SUPER( ) method. For more information, see OpenEdge Development: Progress 4GL Reference .

The super class constructor can only be called once from the subclass constructor and the only place to do this is in the subclass's constructor. It is invalid for the subclass constructor not to call the super class constructor explicitly when the super class constructor has parameters.

Refer, again, to this sample class hierarchy:

Progress.Lang.Object                   <--- Top of hierarchy 
    acme.myObjs.Common.CommonObj 
        acme.myObjs.CustObj 
            acme.myObjs.NECustomer    <--- Bottom of hierarchy 

A class or procedure that executes the NEW statement to instantiate acme.myObjs.NECustomer invokes the acme.myObjs.NECustomer constructor. This constructor must first execute its super class constructor. As previously noted, this can be either an explicit call—with the SUPER statement as the first executable statement—or an implicit call to the acme.myObjs.CustObj constructor. The acme.myObjs.CustObj class, in turn, does the same for its super class constructor in acme.myObjs.Common.CommonObj. Because acme.myObjs.Common.CommonObj is the top of the user-defined class hierarchy, it is the first user-defined constructor to execute to completion.

But before the constructor for acme.myObjs.Common.CommonObj runs, the constructor for the built-in root class, Progress.Lang.Object, is executed, which executes standard startup behavior required by Progress to instantiate classes at run time. The constructor for the top-level user-defined class does not ever need to explicitly invoke the constructor for Progress.Lang.Object. Once the top-level user-defined constructor in acme.myObjs.Common.CommonObj completes, the acme.myObjs.CustObj constructor is executed to completion followed by the acme.myObjs.NECustomer constructor.

If a class or procedure executes another NEW statement for acme.myObjs.NECustomer, the r-code for all classes in the hierarchy is shared with the already instantiated object, but the constructors for all classes are executed again for the new object instance (possibly, with different data).

The following example adds a constructor to the sample subclass, acme.myObjs.NECustomer, described in the "Overriding methods" section. This constructor adds code to initialize the class temp-table, ttEmail, as shown:

CLASS acme.myObjs.NECustomer INHERITS acme.myObjs.CustObj: 
    DEFINE PROTECTED TEMP-TABLE ttEmail NO-UNDO 
        FIELD CustNum LIKE Customer.CustNum 
        FIELD Email AS CHARACTER. 
    CONSTRUCTOR PUBLIC NECustomer ( ): 
        /* Since there are no parameters to the super class's constructor 
           this constructor call is optional */ 
        SUPER( ). 
        /* Code to initialize ttEmail */ 
        ... 
    END CONSTRUCTOR. 
    /* Override method to always get customer name and email */ 
    METHOD PUBLIC OVERRIDE CHARACTER GetCustomerName 
                                     (INPUT piCustNum AS INTEGER): 
        DEFINE VARIABLE CustName AS CHARACTER NO-UNDO. 
        CustName = SUPER:GetCustomerName(INPUT piCustNum). 
        FIND FIRST ttEmail WHERE ttEmail.CustNum = piCustNum. 
        RETURN CustName + ";" + ttEmail.Email. 
    END METHOD. 
END CLASS. 

Constructors can have an access mode of PUBLIC or PROTECTED. The following example demonstrates the use of a PROTECTED constructor. The super class SuperOnly cannot be instantiated directly from outside the class hierarchy, because it does not have a PUBLIC constructor.

Class SuperOnly can only be instantiated by instantiating a class that inherits from it, such as MyPubClass:

CLASS SuperOnly:  
    CONSTRUCTOR PROTECTED SuperOnly ( ): 
    /* An attempt to execute the NEW statement of SuperOnly will work 
     ** only from within the class hierarchy. 
     ** This constructor can only be invoked by a  
     ** subclass object's constructor. 
     */ 
    END CONSTRUCTOR. 
END CLASS. 

CLASS MyPubClass INHERITS SuperOnly:  
     
    CONSTRUCTOR PUBLIC MyPubClass ( ): 
        SUPER( ). /* Invoke the Protected constructor */ 
        /* Perform operations to instantiate this class */ 
        ... 
    END CONSTRUCTOR. 
END CLASS. 

Comparison with procedure-based programming

The syntax for the SUPER statement appears similar to the syntax for the SUPER built-in function, used to invoke user-defined functions in a super procedure. However, unlike the SUPER built-in function, which you must invoke inside an expression in a procedure, you can only invoke the SUPER statement as the first statement in a subclass constructor.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095